package com.gali.mall.service.impl;

import com.gali.mall.common.Const;
import com.gali.mall.exception.GaLiException;
import com.gali.mall.exception.GaLiExceptionEnum;
import com.gali.mall.filiter.UserFilter;
import com.gali.mall.model.dao.*;
import com.gali.mall.model.pojo.Order;
import com.gali.mall.model.pojo.OrderItem;
import com.gali.mall.model.pojo.Product;
import com.gali.mall.model.pojo.User;
import com.gali.mall.model.vo.CartVO;
import com.gali.mall.model.vo.OrderItemVO;
import com.gali.mall.model.vo.OrderVO;
import com.gali.mall.service.OrderService;
import com.gali.mall.utils.CodeUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @author gali
 * @date 2022/4/25 21:27
 */
@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private CartMapper cartMapper;
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private OrderItemMapper orderItemMapper;
    @Autowired
    private UserMapper userMapper;
    /**
     * 添加订单
     *
     * @param order
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String addOrder(Order order) {
        //判断购物车已勾选的商品
        List<CartVO> cartVOS = cartMapper.selectList(order.getUserId());
        ArrayList<CartVO> cartVOListTemp = new ArrayList<>();
        if (cartVOS.size()<0){
            throw  new GaLiException(GaLiExceptionEnum.CART_NOT_PRODUCT);
        }
        for (int i = 0; i < cartVOS.size(); i++) {
            CartVO cartVO = cartVOS.get(i);
            if (cartVO.getSelected().equals(Const.ProductSelected.SELECTED)) {
                cartVOListTemp.add(cartVO);
            }
        }
        cartVOS = cartVOListTemp;
        //判断勾选商品的状态，库存
        checkProductInfo(cartVOS);
        //将购物车变成订单item
        List<OrderItem> orderItems =new ArrayList<>();
        for (int i = 0; i < cartVOS.size(); i++) {
            CartVO cartVO = cartVOS.get(i);
            OrderItem orderItem = new OrderItem();
            orderItem.setProductId(cartVO.getProductId());
            orderItem.setProductName(cartVO.getProductName());
            orderItem.setProductImg(cartVO.getProductImage());
            orderItem.setUnitPrice(cartVO.getTotalPrice());
            orderItem.setQuantity(cartVO.getQuantity());
            orderItem.setTotalPrice(cartVO.getTotalPrice());
            orderItems.add(orderItem);
        }
        //更新库存
        for (int i = 0; i < orderItems.size(); i++) {
            OrderItem orderItem = orderItems.get(i);
            Product product = productMapper.selectByPrimaryKey(orderItem.getProductId());
            int stock = product.getStock() - orderItem.getQuantity();
            if (stock < 0) {
                throw new GaLiException(GaLiExceptionEnum.QUANTITY_NOT_GET);
            }
            product.setStock(stock);
            productMapper.updateByPrimaryKeySelective(product);
        }
            //删除购物车已经勾选了的商品
            for (int i1 = 0; i1 < cartVOS.size(); i1++) {
                CartVO cartVO = cartVOS.get(i1);
                cartMapper.deleteByPrimaryKey(cartVO.getId());
            }

            //生成订单
            String orderNo = UUID.randomUUID().toString();
             order.setOrderNo(orderNo);
            order.setTotalPrice(totalPrice(orderItems));
        int i = orderMapper.insertSelective(order);
        for (int i1 = 0; i1 < orderItems.size(); i1++) {
            OrderItem orderItem = orderItems.get(i1);
            orderItem.setOrderNo(orderNo);
            orderItemMapper.insertSelective(orderItem);
        }
        if (i>0){
            return orderNo;
        }
        throw new GaLiException(GaLiExceptionEnum.ADD_ERROR);
    }
        private Integer totalPrice(List<OrderItem> list) {
            Integer totalPrice = 0;
            for (int i = 0; i < list.size(); i++) {
                OrderItem orderItem = list.get(i);
                totalPrice += orderItem.getTotalPrice();
            }
            return totalPrice;
        }
    private void checkProductInfo(List<CartVO> cartVOS){
        for (int i = 0; i < cartVOS.size(); i++) {
            CartVO cartVO = cartVOS.get(i);
            Product product = productMapper.selectByPrimaryKey(cartVO.getProductId());
            //判断商品是否存在，商品是否上架
            if (product == null || product.getStatus().equals(Const.ProductStatus.NO_STATUS)) {
                throw new GaLiException(GaLiExceptionEnum.PRODUCT_NO_EXIST);
            }
            //判断商品库存
            if (cartVO.getQuantity() > product.getStock()) {
                throw new GaLiException(GaLiExceptionEnum.QUANTITY_NOT_GET);
            }
        }

    }
    /**
     * 删除订单
     *
     * @param id
     * @return
     */
    @Override
    public boolean deleteOrder(Integer id) {
        return orderMapper.deleteByPrimaryKey(id)>0;
    }

    /**
     * 更新订单
     *
     * @param order
     * @return
     */
    @Override
    public boolean reviseOrder(Order order) {
        return orderMapper.updateByPrimaryKeySelective(order)>0;
    }

    /**
     * 查询订单
     *
     * @param id
     * @return
     */
    @Override
    public Order selectOrder(Integer id) {
        return orderMapper.selectByPrimaryKey(id);
    }

    /**
     * 查询订单详情
     * @param orderNo
     * @return
     */
    @Override
    public OrderVO selectByOrderNo(String orderNo) {
        Order order = orderMapper.selectByOrderNo(orderNo);
        if (order==null){
            throw new GaLiException(GaLiExceptionEnum.ORDER_NOT_EXIST);
        }
        Integer id = UserFilter.currentUser.getId();
        if (!id.equals(order.getUserId())){
           throw new GaLiException(GaLiExceptionEnum.ORDER_NOT_EXIST_USER);
        }
        OrderVO order1 = getOrder(order);

        return order1;
    }

    /**
     * 订单列表
     *
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public PageInfo listForCustomer(Integer pageNum, Integer pageSize) {
        Integer userId = UserFilter.currentUser.getId();
        PageHelper.startPage(pageNum,pageSize);
        List<Order> orderList = orderMapper.selectList(userId);
        //将order转化为orderVO
        List<OrderVO> orderVOList = orderListToOrderVOList(orderList);
        //包装成pageInfo进行返回
        PageInfo pageInfo = new PageInfo<>(orderList);
        pageInfo.setList(orderVOList);
        return pageInfo;
    }

    /**
     * 取消订单
     *
     * @param orderNo
     * @return
     */
    @Override
    public boolean cancelOrder(String orderNo) {
        Order order = orderMapper.selectByOrderNo(orderNo);
        if (order == null) {
            throw new GaLiException(GaLiExceptionEnum.PRODUCT_NO_EXIST);
        }
        Integer userId = UserFilter.currentUser.getId();
        if (!order.getUserId().equals(userId)){
            throw new GaLiException(GaLiExceptionEnum.ORDER_NOT_EXIST_USER);
        }
        if (order.getOrderStatus().equals(Const.OrderStatusEnum.NOT_PAY.getCode())){
            //将订单状态设置成取消
            order.setOrderStatus(Const.OrderStatusEnum.CANCELED.getCode());
            order.setEndTime(new Date());
            List<OrderItem> orderItems = orderItemMapper.selectOrderNo(orderNo);
            //返回库存
            for (int i = 0; i < orderItems.size(); i++) {
                OrderItem orderItem = orderItems.get(i);
                Product product = productMapper.selectByPrimaryKey(orderItem.getProductId());
                product.setStock(product.getStock()+orderItem.getQuantity());
                int i1 = productMapper.updateByPrimaryKeySelective(product);
                if (i1<0){
                    throw new GaLiException(GaLiExceptionEnum.UPDATE_ERROR);
                }
            }
            return  orderMapper.updateByPrimaryKeySelective(order)>0;
        }else{
            throw new GaLiException(GaLiExceptionEnum.ORDER_STATUS_NOT_EXIST);
        }
    }

    /**
     * 生成二维码
     *
     * @param orderNo
     * @return
     */
    @Override
    public String code(String orderNo) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String address = Const.FILE_UPLOAD_DIR;
        //支付URL
        String payUrl = "http://baidu.com";
        try {
            CodeUtil.generateQRCodeImage(payUrl,350,350,
                    Const.FILE_UPLOAD_DIR+"/pay/"+orderNo+".png");
        } catch (Exception e) {
            e.printStackTrace();
        }
        String pngAddress= "http://localhost:8081/api/img/pay"+orderNo+".png";
        return pngAddress;
    }

    /**
     * 支付订单
     *
     * @param orderNo
     * @return
     */
    @Override
    public boolean payOrder(String orderNo) {
        Order order = orderMapper.selectByOrderNo(orderNo);
        if (order == null){
            throw new GaLiException(GaLiExceptionEnum.ORDER_NOT_EXIST);
        }
        if (order.getOrderStatus() == Const.OrderStatusEnum.NOT_PAY.getCode()){
            order.setOrderStatus(Const.OrderStatusEnum.PAY.getCode());
            order.setPayTime(new Date());
           return orderMapper.updateByPrimaryKeySelective(order)>0;
        }else {
            throw new GaLiException(GaLiExceptionEnum.ORDER_STATUS_NOT_EXIST);
        }
    }

    /**
     * 订单发货
     *
     * @param orderNo
     * @return
     */
    @Override
    public boolean sendOrder(String orderNo) {
        Order order = orderMapper.selectByOrderNo(orderNo);
        if (order == null){
            throw new GaLiException(GaLiExceptionEnum.ORDER_NOT_EXIST);
        }
        if (order.getOrderStatus() ==Const.OrderStatusEnum.PAY.getCode()){
            order.setOrderStatus(Const.OrderStatusEnum.DELIVERED.getCode());
            order.setPayTime(new Date());
            return orderMapper.updateByPrimaryKeySelective(order)>0;
        }else {
            throw new GaLiException(GaLiExceptionEnum.ORDER_STATUS_NOT_EXIST);
        }
    }

    /**
     * 订单完结
     *
     * @param orderNo
     * @return
     */
    @Override
    public boolean finishOrder(String orderNo) {
        Order order = orderMapper.selectByOrderNo(orderNo);
        User user = userMapper.selectByPrimaryKey(order.getUserId());
        if (order == null){
            throw new GaLiException(GaLiExceptionEnum.ORDER_NOT_EXIST);
        }
        if (!user.getRole().equals(2)&&!UserFilter.currentUser.getId().equals(order.getUserId())){
            throw new GaLiException(GaLiExceptionEnum.ORDER_NOT_EXIST_USER);
        }
        if (order.getOrderStatus() == Const.OrderStatusEnum.DELIVERED.getCode()){
            order.setOrderStatus(Const.OrderStatusEnum.FINISH.getCode());
            order.setEndTime(new Date());
            orderMapper.updateByPrimaryKeySelective(order);
        }else {
            throw new GaLiException(GaLiExceptionEnum.ORDER_STATUS_NOT_EXIST);
        }
        return true;
    }

    /**
     * 订单列表（后台）
     *
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public PageInfo listForAdmin(Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        List<Order> orderList = orderMapper.selectAll();
        //将order转化为orderVO
        List<OrderVO> orderVOList = orderListToOrderVOList(orderList);
        //包装成pageInfo进行返回
        PageInfo pageInfo = new PageInfo<>(orderList);
        pageInfo.setList(orderVOList);
        return pageInfo;
    }

    private List<OrderVO> orderListToOrderVOList(List<Order> orderList) {
        List<OrderVO> orderVOList = new ArrayList<>();
        for (int i = 0; i < orderList.size(); i++) {
            Order order = orderList.get(i);
            OrderVO orderVO = getOrder(order);
            orderVOList.add(orderVO);
        }
        return orderVOList;
    }

    private OrderVO getOrder(Order order) {
        OrderVO orderVO = new OrderVO();
        BeanUtils.copyProperties(order,orderVO);
        //获取订单对应的orderItemVOList
        List<OrderItem> orderItemList = orderItemMapper.selectOrderNo(order.getOrderNo());
        List<OrderItemVO> orderItemVOList = new ArrayList<>();
        for (int i = 0; i < orderItemList.size(); i++){
            OrderItem orderItem = orderItemList.get(i);
            OrderItemVO orderItemVO = new OrderItemVO();
            BeanUtils.copyProperties(orderItem,orderItemVO);
            orderItemVOList.add(orderItemVO);
        }
        orderVO.setItemVOList(orderItemVOList);
        orderVO.setOrderStatusName(Const.OrderStatusEnum.codeOf(orderVO.getOrderStatus()).getValue());
        return orderVO;
    }

}
